package com.wangsd.web.coupon.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.binarywang.wxpay.bean.coupon.WxPayCouponSendRequest;
import com.github.binarywang.wxpay.bean.coupon.WxPayCouponSendResult;
import com.github.binarywang.wxpay.bean.coupon.WxPayCouponStockQueryRequest;
import com.github.binarywang.wxpay.bean.coupon.WxPayCouponStockQueryResult;
import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.wangsd.common.component.WeixinPayService;
import com.wangsd.common.component.WxPayServer;
import com.wangsd.common.exception.BusinessException;
import com.wangsd.common.utils.DateUtils;
import com.wangsd.web.coupon.entity.*;
import com.wangsd.web.coupon.mapper.CouponMapper;
import com.wangsd.web.coupon.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.wangsd.common.enums.CommonStatic.COUPON_TYPE_FREE;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author generator
 * @since 2019-09-24
 */
@Service
public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> implements CouponService {

    @Resource
    CouponMapper couponMapper;
    @Autowired
    CouponStoreService couponStoreService;
    @Autowired
    StoreService storeService;
    @Autowired
    CompanyService companyService;
    @Autowired
    WxPayServer wxPayServer;
    @Autowired
    MemberCouponService memberCouponService;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired
    IntegralDetailService integralDetailService;
    @Autowired
    MerchantService merchantService;
    @Autowired
    CouponService couponService;
    @Autowired
    MemberService memberService;

    @Override
    @Transactional
    public void addOrUpdate(Coupon entity) {
        if (entity.getId() != null) {
            couponMapper.updateById(entity);
            /*删除优惠券与门店的关联关系*/
            QueryWrapper<CouponStore> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("coupon_id", entity.getId());
            couponStoreService.remove(queryWrapper);
        } else {
            WxPayCouponStockQueryResult result = null;
            try {
                WxPayCouponStockQueryRequest request = WxPayCouponStockQueryRequest.newBuilder().build();
                request.setCouponStockId(entity.getCouponStockId());
                Company company = companyService.getById(entity.getCompanyId());
                result = wxPayServer.getWxPayService(company.getBusinessServiceId()).queryCouponStock(request);
            } catch (WxPayException e) {
                throw new BusinessException(e.getErrCodeDes());
            }
            entity.setCouponTotal(result.getCouponTotal());
            entity.setIsSendNum(result.getIsSendNum());
            entity.setCouponStockStatus(result.getCouponStockStatus());
            entity.setMaxQuota(result.getMaxQuota());
            entity.setCouponValue(result.getCouponValue());
            entity.setCouponMininumn(result.getCouponMinimum());
            entity.setBeginTime(DateUtils.timeStamp2Date(result.getBeginTime(), null));
            entity.setEndTime(DateUtils.timeStamp2Date(result.getEndTime(), null));
            couponMapper.insert(entity);
        }
        if (entity.getStoreIds() != null && entity.getStoreIds().size() > 0) {
            for (Long storeId : entity.getStoreIds()) {
                CouponStore item = new CouponStore();
                item.setCouponId(entity.getId());
                item.setStoreId(storeId);
                couponStoreService.save(item);
            }
        }
    }

    @Override
    public IPage<Coupon> selectPage(String code, Integer pageNum, Integer pageSize, Coupon coupon) {
        Page<Coupon> page = new Page<>(pageNum, pageSize);
        IPage<Coupon> couponIPage = couponMapper.selectListXml(page, code, coupon);
        return couponIPage;
    }

    @Override
    public Coupon selectRepeat(String couponStockId, String id) {
        QueryWrapper<Coupon> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("coupon_stock_id", couponStockId);
        if (id != null) {
            queryWrapper.ne("id", id);
        }
        return couponMapper.selectOne(queryWrapper);
    }

    @Override
    @Transactional
    public int updateState(Coupon coupon) {
        int i = couponMapper.updateById(coupon);
        return i;
    }

    @Override
    public List<String> selectStoreById(String id) {

        List<String> resultList = new ArrayList<>();

        QueryWrapper<CouponStore> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("coupon_id", id);
        List<CouponStore> couponStores = couponStoreService.list(queryWrapper);
        /*如果没得关联关系，直接返回空*/
        if (couponStores == null || couponStores.size() <= 0) {
            return resultList;
        }
        /*组装优惠券id*/
        List<Long> storeList = new ArrayList<>();
        for (CouponStore couponStore : couponStores) {
            Long storeId = couponStore.getStoreId();
            storeList.add(storeId);
        }
        List<Long> distinctStores = storeList.stream().distinct().collect(Collectors.toList());

        /*查询所有门店*/
        List<Store> stores = storeService.list(new QueryWrapper<Store>().in("id", distinctStores));
        List<String> codeCollect = stores.stream().map(Store::getCode).collect(Collectors.toList());
        for (String storeCode : codeCollect) {
            /*添加选中的门店code*/
            resultList.add(storeCode);

            /*获取对应的商户code，判断，如果商户code在结果集中已存在，那么就不添加，如过不存在就添加*/
            /*String merchantCode = storeCode.substring(0, storeCode.length() - 2);
            if (resultList.contains(merchantCode)) {
                continue;
            } else {
                resultList.add(merchantCode);
            }*/
        }

        return resultList;
    }

    @Override
    public IPage<Coupon> getHaveCoupon(Integer pageNum, Integer pageSize, String openid, Integer state) {
        Coupon coupon = new Coupon();
        if (0 == state || 2 == state) {
            coupon.setState(state);
            coupon.setEndTime(DateUtils.getCurDate());
        }

        if (0 == state || 1 == state) {
            coupon.setState(state);
        }

        coupon.setOpenid(openid);

        Page<Coupon> page = new Page<>(pageNum, pageSize);
        IPage<Coupon> couponIPage = couponMapper.getHaveCoupon(page, coupon);
        return couponIPage;
    }

    @Override
    public List<Coupon> selectCouponListByCompanyId(Coupon coupon) {

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String beginTime = simpleDateFormat.format(new Date()) + " 00:00:00";
        String endTime = simpleDateFormat.format(new Date()) + " 23:59:59";
        QueryWrapper<Coupon> queryWrapper = new QueryWrapper();
        if (coupon.getBeginTime() != null) {
            queryWrapper.le("begin_time", beginTime);
        }
        if (coupon.getEndTime() != null) {
            queryWrapper.ge("end_time", endTime);
        }
        queryWrapper.eq("company_id", coupon.getCompanyId());
        queryWrapper.select("id,max_quota,coupon_stock_id");
        List<Coupon> list = couponMapper.selectList(queryWrapper);
        return list;
    }

    @Override
    public int quickReceiveCoupon(ServiceBusiness serviceBusiness, Coupon coupon, Member member, Company company) throws BusinessException {
        try {
            WxPayCouponSendRequest request = WxPayCouponSendRequest.newBuilder().build();
            request.setCouponStockId(coupon.getCouponStockId());
            request.setOpenidCount(1);
            request.setPartnerTradeNo(System.currentTimeMillis() + "");

            String strOpenid = stringRedisTemplate.opsForValue().get(member.getMiniOpenid());
            if (StringUtils.isBlank(strOpenid)) {
                throw new BusinessException(9001, "用户未授权！");
            }
            request.setOpenid(strOpenid);
            request.setNonceStr(System.currentTimeMillis() + "");
            WxPayCouponSendResult data = wxPayServer.getWxPayServiceExt(serviceBusiness).sendCoupon(request);
            log.debug("data.getRetCode()==" + data.getRetCode());
            if ("SUCCESS".equals(data.getRetCode())) {
                MemberCoupon memberCoupon = new MemberCoupon();

                memberCoupon.setId(Long.valueOf(data.getCouponId()));
                memberCoupon.setOpenid(member.getMiniOpenid());
                memberCoupon.setWxCouponId(Long.valueOf(data.getCouponId()));
                memberCoupon.setStockId(coupon.getCouponStockId());
                memberCoupon.setMemberId(member.getId());
                memberCoupon.setType(1);
                memberCouponService.save(memberCoupon);

                /*修改优惠券已发送的数量*/
                Coupon updateCoupon = new Coupon();
                updateCoupon.setId(coupon.getId());
                updateCoupon.setIsSendNum(coupon.getIsSendNum()+1);
                couponMapper.updateById(updateCoupon);
            } else {
                return -1;
            }
        } catch (WxPayException e) {
            throw new BusinessException(9002, e.getErrCodeDes());
        }
        return 0;
    }

    @Override
    public int saveTrade(JSONObject requestContent) {
        /**
         * 支付商户信息
         */
        JSONObject paymchkey = requestContent.getJSONObject("pay_mch_key");
        String out_mch_id = paymchkey.getString("out_mch_id");
        String out_shop_id = paymchkey.getString("out_shop_id");
        String out_sub_mch_id = paymchkey.getString("out_sub_mch_id");
        Integer pay_platform = paymchkey.getInteger("pay_platform");
        String openid = paymchkey.getJSONObject("wxpay_pay_mch_key_ext").getString("open_id");
        //子商户号
        String sub_mch_id = paymchkey.getJSONObject("wxpay_pay_mch_key_ext").getString("sub_mch_id");

        /**
         * 订单信息
         */
        JSONObject orderContent = requestContent.getJSONObject("order_content");
        //商户定义订单号
        String out_trade_no = orderContent.getString("out_trade_no");
        //第三方支付平台的订单号
        String transaction_id = orderContent.getString("transaction_id");
        //商品或订单简要描述
        String title = orderContent.getString("body");
        //支付完成时间
        String time_end = orderContent.getString("time_end");
        String payDate = DateUtils.timeStamp2Date(time_end, null);
        //支付总金额单位分
        Integer total_fee = orderContent.getInteger("total_fee");
        //现金支付金额单位分
        Integer cash_fee = orderContent.getInteger("cash_fee");
        //应结支付金额
        Integer settlement_total_fee = orderContent.getInteger("settlement_total_fee");
        //支付用户的openid
        String user_identity = orderContent.getString("user_identity");

        /**
         * 微信支付扩展信息
         */
        JSONObject wxpayOrderContentExt = orderContent.getJSONObject("wxpay_order_content_ext");
        int coupon_count = wxpayOrderContentExt.getInteger("coupon_count");

        Store store = storeService.getOne(new QueryWrapper<Store>().eq("out_shop_id", out_shop_id));
        Merchant merchant = merchantService.getById(store.getMerchantId());
        /*if(merchant.getCompanyId()!=28){
            return -1;
        }*/
        Member member = null;
        //核销优惠券
        if (coupon_count > 0) {
            String[] split = store.getCode().split("-");
            WxPayService wxPayService = wxPayServer.getWxPayService(Long.valueOf(split[0]));
            WxPayConfig payConfig = wxPayService.getConfig();
            payConfig.setSubMchId(sub_mch_id);
            wxPayService.setConfig(payConfig);
            //代金券或立减优惠 id
            String coupon_id = null;
            try {
                WxPayOrderQueryResult data = wxPayService.queryOrder(transaction_id, "");
                coupon_id = data.getCoupons().get(0).getCouponId();
            } catch (WxPayException e) {
                e.printStackTrace();
            }

            JSONArray coupon_infos = orderContent.getJSONArray("coupon_infos");
            //单个代金券或立减优惠支付金额
            Integer coupon_fee = coupon_infos.getJSONObject(0).getInteger("coupon_fee");
            //代金券类型，CASH--充值代金券, NO_CASH---非充值代金券
            String coupon_type = coupon_infos.getJSONObject(0).getString("coupon_type");
            MemberCoupon memberCoupon = new MemberCoupon();
            memberCoupon.setState(1);
            memberCoupon.setWxCouponId(Long.valueOf(coupon_id));
            memberCoupon.setOutShopId(out_shop_id);
            memberCouponService.verificationCoupon(memberCoupon);
            //查询已领取的优惠券
            MemberCoupon old = memberCouponService.getOne(new QueryWrapper<MemberCoupon>().eq("wx_coupon_id",coupon_id));
            if (old != null && old.getState() == 0) {//未核销
                //memberCouponService.update(memberCoupon);
                memberCoupon.setState(1);
                memberCouponService.verificationCoupon(memberCoupon);
                //更新优惠券核销数量
                /*Coupon coupon = couponService.getOne(new QueryWrapper<Coupon>().eq("coupon_id",coupon_id));
                product.setVerification(coupon.get() + 1);
                productService.update(product);*/
                member = memberService.selectByOpenid2(openid, merchant.getCompanyId());
                //增加会员积分
                if (member != null) {
                    //支付总金额单位分
                    member.setIntegral(member.getIntegral() + total_fee / 100);
                    /*设置成认证会员*/
                    if (member.getMobile() != null && member.getAvatarUrl() != null) {
                        member.setStatus(1);
                    }
                    memberService.save(member);
                }
            }
        }

        /*签到完成之后，向积分明细表中添加积分明细数据*/
        IntegralDetail integralDetail = new IntegralDetail();
        integralDetail.setCreatedTime(new Date());
        integralDetail.setOpenId(member == null ? openid : member.getMiniOpenid());
        /*加积分*/
        integralDetail.setStatus(1);
        integralDetail.setIntegral(total_fee);
        /*云支付回调*/
        integralDetail.setType(1);
        integralDetailService.save(integralDetail);

        return 1;
    }
}
